// Copyright (c) 2023 刻BITTER
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.


#pragma once


#include <stdint.h>

#include <oled_basic_low_level_common.hpp>


namespace oled_basic {
    
    template <typename Child>
    struct Ssd13xxProtocol {
        static void enable_inverse_display() {
            Child::write_byte(0xA7, write_mode::cmd);  // 反色显示
        }


        static void disable_inverse_display() {
            Child::write_byte(0xA6, write_mode::cmd);  // 反色显示
        }


        static void enable_screen_flip() {
            Child::write_byte(0xC8, write_mode::cmd);  // 反转显示
            Child::write_byte(0xA0, write_mode::cmd);
        }


        static void disable_screen_flip() {
            Child::write_byte(0xC0, write_mode::cmd);  // 正常显示
            Child::write_byte(0xA1, write_mode::cmd);
        }


        /**
         * @brief 设置坐标
         *
         * page addressing 模式，列地址超过127 溢出后自动返回0
         *
         * @param x 列地址
         * @param y 页地址
         */
        static void set_position(uint8_t column, uint8_t page) {
            Child::write_byte(0xb0 + page, write_mode::cmd);
            Child::write_byte(((column & 0xf0) >> 4) | 0x10, write_mode::cmd);
            Child::write_byte(column & 0x0f, write_mode::cmd);
        }


        // 开启OLED显示
        static void display_on(void) {
            Child::write_byte(0X8D, write_mode::cmd);  // SET DCDC命令
            Child::write_byte(0X14, write_mode::cmd);  // DCDC ON
            Child::write_byte(0XAF, write_mode::cmd);  // DISPLAY ON
        }


        // 关闭OLED显示
        static void display_off(void) {
            Child::write_byte(0X8D, write_mode::cmd);  // SET DCDC命令
            Child::write_byte(0X10, write_mode::cmd);  // DCDC OFF
            Child::write_byte(0XAE, write_mode::cmd);  // DISPLAY OFF
        }
    };

}  // namespace oled_basic